package zj.service.modules.sign.service;

import com.github.crab2died.ExcelUtils;
import com.zj.util.base.eo.DatePattern;
import com.zj.util.base.eo.Week;
import com.zj.util.utils.DateUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import zj.service.modules.sign.domain.SignRecord;
import zj.service.modules.sign.domain.Staff;
import zj.service.modules.sign.repository.SignRecordRepository;
import zj.service.modules.sign.repository.StaffRepository;
import zj.service.modules.sign.util.SignDataModel;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author xi.yang
 * @create 2018-05-25 上午 10:05
 **/
@Service
public class SignRecordService {
    private static final Logger logger = LoggerFactory.getLogger(SignRecordService.class);
    private static final String START_TIME = "09:00";
    private static final String START_OVER_TIME = "09:30";
    private static final String END_TIME = "18:00";
    private static final String OVER_TIME = "20:00";
    private static final String OVER_END_TIME = "21:00";
    private static final Long WORK_DAY_HOURS = 9L;

    private static final Date startLimit = DateUtil.parseDate(START_TIME);
    private static final Date startOverLimit = DateUtil.parseDate(START_OVER_TIME);
    private static final Date endLimit = DateUtil.parseDate(END_TIME);
    private static final Date overLimit = DateUtil.parseDate(OVER_TIME);
    private static final Date overEndLimit = DateUtil.parseDate(OVER_END_TIME);

    @Autowired
    SignRecordRepository signRecordRepository;
    @Autowired
    StaffRepository staffRepository;

    public void addSignRecords(String filePath) {
        List<SignDataModel> datas = null;
        try {
            datas = ExcelUtils.getInstance().readExcel2Objects(filePath, SignDataModel.class);
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("read excel error : === {}", filePath);
        }
        if (null == datas || datas.size() == 0) {
            return;
        }
//        更新员工表
        List<Staff> staffs = new ArrayList<>();
        for (SignDataModel data : datas) {
            String name = data.getName();
            if (isInStaffs(staffs, name)) {
                continue;
            }
            Staff staff = new Staff();
            staff.setName(name);
            staffs.add(staff);
        }
        for (Staff staff : staffs) {
            if (staffRepository.existsByName(staff.getName())) {
                continue;
            }
            staffRepository.save(staff);
        }
//        更新打卡记录
        List<SignRecord> signRecords = new ArrayList<>();
        for (SignDataModel data : datas) {
            String name = data.getName();
            Date time = data.getSignTime();
            Date dateStr = DateUtil.parseDate(DateUtil.fmtDate(time, DatePattern.yyyyMMdd));
            SignRecord signRecord = getSignRecord(signRecords, name, dateStr);
            if (signRecord == null) {
                signRecord = new SignRecord();
                signRecord.setDateStr(dateStr);
                Staff staff = staffRepository.findByName(name);
                signRecord.setStaff(staff);
                List<Date> dateList = new ArrayList<>();
                dateList.add(time);
                signRecord.setTimes(dateList);
                signRecords.add(signRecord);
                continue;
            }
            signRecord.getTimes().add(time);
        }

        for (SignRecord signRecord : signRecords) {
            List<Date> times = signRecord.getTimes();

            SignRecord exist = signRecordRepository.getByStaffAndDateStr(signRecord.getStaff(), signRecord.getDateStr());
            if (exist != null) {
                signRecord.setId(exist.getId());
                for (Date time : exist.getTimes()) {
                    if (notInTimes(times, time)) {
                        times.add(time);
                    }
                }
            }
            Date startTime = times.get(0);
            Date endTime = times.get(0);
            for (Date time : times) {
                if (startTime.getTime() > time.getTime()) {
                    startTime = time;
                }
                if (endTime.getTime() < time.getTime()) {
                    endTime = time;
                }
            }
            signRecord.setStartTime(startTime);
            signRecord.setEndTime(endTime);
            signRecordRepository.save(signRecord);
        }
    }

    private boolean notInTimes(List<Date> times, Date time) {
        for (Date date : times) {
            if (date.getTime() == time.getTime()) {
                return false;
            }
        }
        return true;
    }

//    private void completeOtherTime(SignRecord signRecord) {
//        final Date startTime = signRecord.getStartTime();
//        final Date endTime = signRecord.getEndTime();
//        //  2018/8/29 加班弹性计算
//        if (isFreeTime(signRecord.getDateStr())) {
//            final long hours = DateUtil.getHoursBetween(startTime, endTime);
//            if (hours >= 9) {
//                signRecord.setAllRight(true);
//            }
//            signRecord.setFreeTime(true);
//            signRecord.setOverTime(true);
//            return;
//        }
//        //  2018/8/29 正常时间
//        final Date start = DateUtil.parseDate(DateUtil.fmtDate(startTime,DatePattern.HHmm));
//        final Date end = DateUtil.parseDate(DateUtil.fmtDate(endTime, DatePattern.HHmm));
////        判断是否算加班并计算加班时长
//        if (end.getTime() >= overLimit.getTime()) {
//            //  2018/8/28 6:30开始算加班，所以要-1
//            long halfHours = DateUtil.getHalfHoursBetween(endLimit, end)-1;
//            if (halfHours > 0) {
//                signRecord.setHalfHours(halfHours);
//            }
//            signRecord.setOverTime(true);
//        }
//        boolean startRight = isStartRight(start, signRecord);
//        boolean endRight = isEndRight(end, signRecord);
//        if (startRight && endRight) {
//            signRecord.setAllRight(true);
//        }
//    }

    private boolean isEndRight(Date end, SignRecord signRecord) {
//        正常打卡
        if (end.getTime() >= endLimit.getTime()) {
            return true;
        }
//        24号不算结束时间
        int day = DateUtil.getDayOfMonth(signRecord.getDateStr());
        if (day == 24) {
            return true;
        }
        return false;
    }

    private boolean isStartRight(Date start, SignRecord signRecord) {
//        正常打卡
        if (start.getTime() <= startLimit.getTime()) {
            return true;
        }
//        迟到半小时，判断是否是前一天加班
        if (start.getTime() <= startOverLimit.getTime()) {
            SignRecord perDateSign = signRecordRepository.getByStaffAndDateStr(signRecord.getStaff(), DateUtil.addDays(signRecord.getDateStr(), -1));
            if (null != perDateSign && perDateSign.getEndTime().getTime() >= overEndLimit.getTime()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 判断是否加班
     *
     * @param date
     * @return
     */
    private boolean isFreeTime(Date date) {
        // TODO: 2018/8/28 这里只用暂时周末来做判断是否是加班
        final Week week = DateUtil.getWeek(date);
        if (Week.SATURDAY.equals(week) || Week.SUNDAY.equals(week)) {
            return true;
        }
        return false;
    }

    private SignRecord getSignRecord(List<SignRecord> signRecords, String name, Date dateStr) {
        for (SignRecord signRecord : signRecords) {
            if (signRecord.getDateStr().equals(dateStr) && signRecord.getStaff().getName().equals(name)) {
                return signRecord;
            }
        }
        return null;
    }

    private boolean isInStaffs(List<Staff> staffs, String name) {
        for (Staff staff : staffs) {
            if (staff.getName().equals(name)) {
                return true;
            }
        }
        return false;
    }
}
